home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / SpriteFight 2002 v2.0a1 / Frame.c < prev    next >
Text File  |  1994-04-26  |  13KB  |  593 lines

  1. ///--------------------------------------------------------------------------------------
  2. //    Frame.c
  3. //
  4. //    Created:    Sunday, November 15, 1992 at 2:37:37 AM
  5. //    By:        Tony Myles
  6. //
  7. //    Copyright: © 1991-94 Tony Myles, All rights reserved worldwide
  8. //
  9. //    Description:    implementation of the frame stuff
  10. ///--------------------------------------------------------------------------------------
  11.  
  12.  
  13. #ifndef __SWCOMMON__
  14. #include "SWCommonHeaders.h"
  15. #endif
  16.  
  17. #ifndef __TOOLUTILS__
  18. #include <ToolUtils.h>
  19. #endif
  20.  
  21. #ifndef __MEMORY__
  22. #include <Memory.h>
  23. #endif
  24.  
  25. #ifndef __RESOURCES__
  26. #include <Resources.h>
  27. #endif
  28.  
  29. #ifndef __ERRORS__
  30. #include <Errors.h>
  31. #endif
  32.  
  33. #ifndef __SPRITEWORLDUTILS__
  34. #include "SpriteWorldUtils.h"
  35. #endif
  36.  
  37. #ifndef __SPRITECOMPILER__
  38. #include "SpriteCompiler.h"
  39. #endif
  40.  
  41. #ifndef __FRAME__
  42. #include "Frame.h"
  43. #endif
  44.  
  45. #if MPW
  46. #pragma segment SpriteWorld
  47. #endif
  48.  
  49. ///--------------------------------------------------------------------------------------
  50. //    SWCreateFrame
  51. ///--------------------------------------------------------------------------------------
  52.  
  53. SW_FUNC OSErr SWCreateFrame(
  54.     FramePtr* newFrameP,
  55.     CGrafPtr srcGrafP,
  56.     Rect* frameRect)
  57. {
  58.     OSErr err = noErr;
  59.     FramePtr tempFrameP;
  60.     short bitsPerPixel;
  61.     long numScanLines;
  62.     
  63.     numScanLines = frameRect->bottom - frameRect->top;
  64.  
  65.     *newFrameP = NULL;
  66.  
  67.     tempFrameP = (FramePtr)NewPtrClear((Size)sizeof(FrameRec) + (sizeof(unsigned long) * numScanLines));
  68.  
  69.     if (tempFrameP != NULL)
  70.     {
  71.         tempFrameP->isColor = SWHasColorQuickDraw();
  72.  
  73.         if (srcGrafP == NULL)
  74.         {
  75.             if (tempFrameP->isColor)
  76.             {
  77.                 err = SWCreateBestCGrafPort(&tempFrameP->framePort.colorGrafP, frameRect);
  78.             }
  79.             else
  80.             {
  81.                 err = SWCreateGrafPort(&tempFrameP->framePort.monoGrafP, frameRect);
  82.             }
  83.         }
  84.         else
  85.         {
  86.             tempFrameP->framePort.colorGrafP = srcGrafP;
  87.         }
  88.  
  89.         if (err == noErr)
  90.         {
  91.             tempFrameP->frameRect = tempFrameP->framePort.colorGrafP->portRect;
  92.  
  93.                 // cache frameRowBytes and frameRowLongs for use by our blitter routine
  94.             tempFrameP->frameRowBytes = tempFrameP->isColor ?
  95.                     (**tempFrameP->framePort.colorGrafP->portPixMap).rowBytes & 0x7FFF :
  96.                     tempFrameP->framePort.monoGrafP->portBits.rowBytes;
  97.  
  98.             tempFrameP->frameRowLongs = (tempFrameP->frameRect.right -
  99.                     tempFrameP->frameRect.left) >> 2;
  100.  
  101.                 // this calculation generates a mask value that we use to
  102.                 // long word align the rectangle when we draw the frame.
  103.                 // note that the expression "sizeof(long) * kBitsPerByte" gives us
  104.                 // the number of bits in a long.
  105.             bitsPerPixel = tempFrameP->isColor ?
  106.                     (**tempFrameP->framePort.colorGrafP->portPixMap).pixelSize : 1;            
  107.             tempFrameP->rightAlignFactor = ((sizeof(long) * kBitsPerByte) / bitsPerPixel) - 1;
  108.             tempFrameP->leftAlignFactor = ~(tempFrameP->rightAlignFactor);
  109.  
  110.                 // the useCount keeps track of the number of sprites that
  111.                 // are using this frame. we need to know this so we don't
  112.                 // dispose this frame twice when we are disposing the 
  113.                 // sprites that use it.
  114.             tempFrameP->useCount = 0;
  115.  
  116.                 // here we set up an array of offsets to the scan lines of
  117.                 // this frame. this allows us to address a particular scan line
  118.                 // without doing a costly multiply.
  119.             tempFrameP->numScanLines = numScanLines;
  120.             tempFrameP->scanLinePtrArray = (unsigned long*)(tempFrameP + 1);
  121.  
  122.             for (numScanLines = 0; numScanLines < tempFrameP->numScanLines; numScanLines++)
  123.             {
  124.                 tempFrameP->scanLinePtrArray[numScanLines] = (numScanLines * tempFrameP->frameRowBytes);
  125.             }
  126.  
  127.  
  128.             *newFrameP = tempFrameP;
  129.         }
  130.     }
  131.     else
  132.     {
  133.         err = MemError();
  134.     }
  135.  
  136.     if (err != noErr)
  137.     {
  138.         if (tempFrameP != NULL)
  139.         {
  140.             if (tempFrameP->framePort.colorGrafP != NULL)
  141.             {
  142.                 if (tempFrameP->isColor)
  143.                 {
  144.                     SWDisposeCGrafPort(tempFrameP->framePort.colorGrafP);
  145.                 }
  146.                 else
  147.                 {
  148.                     SWDisposeGrafPort((GrafPtr)tempFrameP->framePort.monoGrafP);
  149.                 }
  150.             }
  151.  
  152.             DisposePtr((Ptr)tempFrameP);
  153.         }
  154.     }
  155.  
  156.     return err;
  157. }
  158.  
  159.  
  160. ///--------------------------------------------------------------------------------------
  161. //    SWCreateFrameFromCIconResource
  162. ///--------------------------------------------------------------------------------------
  163.  
  164. SW_FUNC OSErr SWCreateFrameFromCIconResource(
  165.     FramePtr* newFrameP,
  166.     short iconResID,
  167.     MaskType maskType)
  168. {
  169.     OSErr err;
  170.     GrafPtr savePort;
  171.     FramePtr tempFrameP;
  172.     CIconHandle cIconH;
  173.     RgnHandle maskRgn;
  174.     Rect frameRect;
  175.  
  176.     *newFrameP = NULL;
  177.     tempFrameP = NULL;
  178.     cIconH = NULL;
  179.  
  180.     GetPort(&savePort);
  181.  
  182.     err = SWGetCIcon(&cIconH, iconResID);
  183.  
  184.     if (err == noErr)
  185.     {
  186.         HNoPurge((Handle)cIconH);
  187.  
  188.         frameRect = (**cIconH).iconPMap.bounds;
  189.  
  190.         err = SWCreateFrame(&tempFrameP, NULL, &frameRect);
  191.     }
  192.  
  193.     if (err == noErr)
  194.     {
  195.         SetPort(tempFrameP->framePort.monoGrafP);
  196.  
  197.         SWPlotCIcon(cIconH, &frameRect);
  198.     }
  199.  
  200.     if (err == noErr)
  201.     {
  202.             // make a region mask
  203.         if ((maskType & kRegionMask) != 0)
  204.         {
  205.             err = SWCreateRegionFromCIconMask(&maskRgn, cIconH);
  206.  
  207.             if (err == noErr)
  208.             {
  209.                 SWSetFrameMaskRgn(tempFrameP, maskRgn);
  210.             }
  211.         }
  212.     }
  213.  
  214.     if (err == noErr)
  215.     {
  216.             // make a pixel mask
  217.         if ((maskType & kPixelMask) != 0)
  218.         {
  219.             if (tempFrameP->isColor)
  220.             {
  221.                 err = SWCreateCGrafPortFromCIconMask(&tempFrameP->maskPort.colorGrafP, cIconH);
  222.             }
  223.             else
  224.             {
  225.                 err = SWCreateGrafPortFromCIconMask(&tempFrameP->maskPort.monoGrafP, cIconH);
  226.             }
  227.  
  228.                 // %%% pre-xor mask experiment
  229.             if (err == noErr)
  230.             {
  231.                 SetPort(tempFrameP->maskPort.monoGrafP);
  232.                 InvertRect(&tempFrameP->maskPort.monoGrafP->portRect);
  233.             }
  234.         }
  235.     }
  236.  
  237.     if (err == noErr)
  238.     {
  239.             // load compiled mask
  240.         if ((maskType & kCompiledMask) != 0)
  241.         {
  242.             tempFrameP->pixCodeH = (PixelCodeHdl)GetResource(kPixelCodeResType, iconResID);
  243.             err = ResError();
  244.  
  245.             if ((tempFrameP->pixCodeH == NULL) && (err == noErr))
  246.                 err = resNotFound;
  247.  
  248.             if (err == noErr)
  249.             {
  250.                 HNoPurge((Handle)tempFrameP->pixCodeH);
  251.                 DetachResource((Handle)tempFrameP->pixCodeH);
  252.             }
  253.         }
  254.     }
  255.  
  256.     if (cIconH != NULL)
  257.     {
  258.         SWDisposeCIcon(cIconH);
  259.     }
  260.  
  261.     if (err == noErr)
  262.     {
  263.         *newFrameP = tempFrameP;
  264.     }
  265.  
  266.     if (err != noErr)
  267.     {
  268.             // an error occurred so dispose of anything we managed to create
  269.         if (tempFrameP != NULL)
  270.         {
  271.             SWDisposeFrame(tempFrameP);
  272.         }
  273.     }
  274.  
  275.     SetPort(savePort);
  276.  
  277.     return err;
  278. }
  279.  
  280.  
  281. ///--------------------------------------------------------------------------------------
  282. //    SWCreateFrameFromPictResource
  283. ///--------------------------------------------------------------------------------------
  284.  
  285. SW_FUNC OSErr SWCreateFrameFromPictResource(
  286.     FramePtr* newFrameP,
  287.     short pictResID,
  288.     short maskResID,
  289.     MaskType maskType)
  290. {
  291.     OSErr err;
  292.     GrafPtr savePort;
  293.     PicHandle newPictH;
  294.     FramePtr tempFrameP;
  295.     RgnHandle maskRgn;
  296.     Rect frameRect;
  297.  
  298.     tempFrameP = NULL;
  299.     *newFrameP = NULL;
  300.  
  301.     GetPort(&savePort);
  302.  
  303.     newPictH = GetPicture(pictResID);
  304.  
  305.     if (newPictH != NULL)
  306.     {
  307.         frameRect.top = 0;
  308.         frameRect.left = 0;
  309.         frameRect.right = (**newPictH).picFrame.right - (**newPictH).picFrame.left;
  310.         frameRect.bottom = (**newPictH).picFrame.bottom - (**newPictH).picFrame.top;
  311.  
  312.         err = SWCreateFrame(&tempFrameP, NULL, &frameRect);
  313.  
  314.         if (err == noErr)
  315.         {
  316.             SetPort(tempFrameP->framePort.monoGrafP);
  317.  
  318.             DrawPicture(newPictH, &frameRect);
  319.         }
  320.  
  321.             // make a region mask
  322.         if (((maskType & kRegionMask) != 0) && (err == noErr))
  323.         {
  324.             err = SWCreateRegionFromPictResource(&maskRgn, maskResID);
  325.  
  326.             if (err == noErr)
  327.             {
  328.                 SWSetFrameMaskRgn(tempFrameP, maskRgn);
  329.             }
  330.         }
  331.  
  332.             // make a pixel mask
  333.         if (((maskType & kPixelMask) != 0) && (err == noErr))
  334.         {
  335.             if (tempFrameP->isColor)
  336.             {
  337.                 err = SWCreateCGrafPortFromPictResource(&tempFrameP->maskPort.colorGrafP, maskResID);
  338.             }
  339.             else
  340.             {
  341.                 err = SWCreateGrafPortFromPictResource(&tempFrameP->maskPort.monoGrafP, maskResID);
  342.             }
  343.  
  344.                 // %%% pre-xor mask experiment
  345.             if (err == noErr)
  346.             {
  347.                 SetPort(tempFrameP->maskPort.monoGrafP);
  348.                 InvertRect(&tempFrameP->maskPort.monoGrafP->portRect);
  349.             }
  350.         }
  351.  
  352.         if (err == noErr)
  353.         {
  354.             *newFrameP = tempFrameP;
  355.         }
  356.         else
  357.         {
  358.                 // an error occurred so dispose of anything we managed to create
  359.             if (tempFrameP != NULL)
  360.             {
  361.                 SWDisposeFrame(tempFrameP);
  362.             }
  363.         }
  364.  
  365.         ReleaseResource((Handle)newPictH);
  366.     }
  367.     else
  368.     {
  369.         err = ResError();
  370.  
  371.         if (err == noErr)
  372.         {
  373.             err = resNotFound;
  374.         }
  375.     }
  376.  
  377.     SetPort(savePort);
  378.  
  379.     return err;
  380. }
  381.  
  382.  
  383. ///--------------------------------------------------------------------------------------
  384. //    SWDisposeFrame
  385. ///--------------------------------------------------------------------------------------
  386.  
  387. SW_FUNC void SWDisposeFrame(
  388.     FramePtr oldFrameP)
  389. {
  390.     if (oldFrameP != NULL)
  391.     {
  392.             // is this frame still in use by another sprite?
  393.         if (oldFrameP->useCount > 1)
  394.         {
  395.                 // one less sprite is using it now!
  396.             oldFrameP->useCount--;
  397.         }
  398.         else    // no more sprites are using this frame
  399.         {
  400.             if (oldFrameP->framePort.colorGrafP != NULL)
  401.             {
  402.                 if (oldFrameP->isColor)
  403.                 {
  404.                     SWDisposeCGrafPort(oldFrameP->framePort.colorGrafP);
  405.                 }
  406.                 else
  407.                 {
  408.                     SWDisposeGrafPort(oldFrameP->framePort.monoGrafP);
  409.                 }
  410.     
  411.                 oldFrameP->framePort.colorGrafP = NULL;
  412.             }
  413.  
  414.             if (oldFrameP->maskRgn != NULL)
  415.             {
  416.                 DisposeRgn(oldFrameP->maskRgn);
  417.     
  418.                 oldFrameP->maskRgn = NULL;
  419.             }
  420.  
  421.             if (oldFrameP->maskPort.colorGrafP != NULL)
  422.             {
  423.                 if (oldFrameP->isColor)
  424.                 {
  425.                     SWDisposeCGrafPort(oldFrameP->maskPort.colorGrafP);
  426.                 }
  427.                 else
  428.                 {
  429.                     SWDisposeGrafPort(oldFrameP->maskPort.monoGrafP);
  430.                 }
  431.  
  432.                 oldFrameP->maskPort.colorGrafP = NULL;
  433.             }
  434.  
  435.             if (oldFrameP->pixCodeH != NULL)
  436.             {
  437.                 DisposeHandle((Handle)oldFrameP->pixCodeH);
  438.                 oldFrameP->pixCodeH = NULL;
  439.             }
  440.  
  441.             DisposePtr((Ptr)oldFrameP);
  442.         }
  443.     }
  444. }
  445.  
  446.  
  447. ///--------------------------------------------------------------------------------------
  448. //    SWSetFrameMaskRgn
  449. ///--------------------------------------------------------------------------------------
  450.  
  451. SW_FUNC void SWSetFrameMaskRgn(
  452.     FramePtr srcFrameP,
  453.     RgnHandle maskRgn)
  454. {
  455.     srcFrameP->maskRgn = maskRgn;
  456.  
  457.     srcFrameP->offsetPoint.h = (**maskRgn).rgnBBox.left;
  458.     srcFrameP->offsetPoint.v = (**maskRgn).rgnBBox.top;
  459. }
  460.  
  461.  
  462. ///--------------------------------------------------------------------------------------
  463. //    SWGetFrameMaskRgn
  464. ///--------------------------------------------------------------------------------------
  465.  
  466. SW_FUNC RgnHandle SWGetFrameMaskRgn(
  467.     FramePtr srcFrameP)
  468. {
  469.     return srcFrameP->maskRgn;
  470. }
  471.  
  472.  
  473. ///--------------------------------------------------------------------------------------
  474. //    SWLockFrame
  475. ///--------------------------------------------------------------------------------------
  476.  
  477. SW_FUNC void SWLockFrame(
  478.     FramePtr srcFrameP)
  479. {
  480.     srcFrameP->isFrameLocked = true;
  481.  
  482.     if (srcFrameP->isColor)
  483.     {
  484.         PixMapHandle pixMapH;
  485.  
  486.         pixMapH = srcFrameP->framePort.colorGrafP->portPixMap;
  487.         HLock((Handle)pixMapH);
  488.  
  489.         srcFrameP->framePix.pixMapP = *pixMapH;
  490.         srcFrameP->frameBaseAddr = (**pixMapH).baseAddr;
  491.         srcFrameP->frameRowBytes = (**pixMapH).rowBytes & 0x7FFF;
  492.  
  493.         if (srcFrameP->pixCodeH != NULL)
  494.         {
  495.             HLock((Handle)srcFrameP->pixCodeH);
  496.             srcFrameP->frameBlitterP = (BlitFuncPtr)*srcFrameP->pixCodeH;
  497.         }
  498.  
  499.         if (srcFrameP->maskPort.colorGrafP != NULL)
  500.         {
  501.             pixMapH = srcFrameP->maskPort.colorGrafP->portPixMap;
  502.             HLock((Handle)pixMapH);
  503.  
  504.             srcFrameP->isMaskLocked = true;
  505.  
  506.             srcFrameP->maskPix.pixMapP = *pixMapH;
  507.  
  508.             srcFrameP->maskBaseAddr = (**pixMapH).baseAddr;
  509.         }
  510.     }
  511.     else
  512.     {
  513.         srcFrameP->framePix.bitMapP = &srcFrameP->framePort.monoGrafP->portBits;
  514.         srcFrameP->frameBaseAddr = srcFrameP->framePix.bitMapP->baseAddr;
  515.  
  516.         if (srcFrameP->maskPort.monoGrafP != NULL)
  517.         {
  518.             srcFrameP->maskPix.bitMapP = &srcFrameP->maskPort.monoGrafP->portBits;
  519.             srcFrameP->maskBaseAddr = srcFrameP->maskPix.bitMapP->baseAddr;
  520.         }
  521.     }
  522. }
  523.  
  524.  
  525. ///--------------------------------------------------------------------------------------
  526. //    SWUnlockFrame
  527. ///--------------------------------------------------------------------------------------
  528.  
  529. SW_FUNC void SWUnlockFrame(
  530.     FramePtr srcFrameP)
  531. {
  532.     if (srcFrameP->isColor)
  533.     {
  534.         if (srcFrameP->framePort.colorGrafP != NULL)
  535.         {
  536.             HUnlock((Handle)srcFrameP->framePort.colorGrafP->portPixMap);
  537.         }
  538.  
  539.         if (srcFrameP->maskPort.colorGrafP != NULL)
  540.         {
  541.             HUnlock((Handle)srcFrameP->maskPort.colorGrafP->portPixMap);
  542.         }
  543.     }
  544.  
  545.     srcFrameP->isFrameLocked = false;
  546.     srcFrameP->isMaskLocked = false;
  547.  
  548.     srcFrameP->framePix.pixMapP = NULL;
  549.     srcFrameP->frameBaseAddr = NULL;
  550.     srcFrameP->maskPix.pixMapP = NULL;
  551.     srcFrameP->maskBaseAddr = NULL;
  552.  
  553.     if (srcFrameP->pixCodeH != NULL)
  554.     {
  555.         HUnlock((Handle)srcFrameP->pixCodeH);
  556.         srcFrameP->frameBlitterP = NULL;
  557.     }
  558. }
  559.  
  560.  
  561. ///--------------------------------------------------------------------------------------
  562. //    SWCopyFrame
  563. ///--------------------------------------------------------------------------------------
  564.  
  565. SW_FUNC void SWCopyFrame(
  566.     FramePtr srcFrameP,
  567.     FramePtr dstFrameP)
  568. {
  569.     if (srcFrameP->isFrameLocked)
  570.     {
  571.         CopyBits(srcFrameP->framePix.bitMapP,
  572.                     dstFrameP->framePix.bitMapP,
  573.                     &srcFrameP->frameRect,
  574.                     &srcFrameP->frameRect,
  575.                     srcCopy, srcFrameP->maskRgn);
  576.     }
  577. }
  578.  
  579.  
  580. ///--------------------------------------------------------------------------------------
  581. //    SWSetFrameRect
  582. ///--------------------------------------------------------------------------------------
  583.  
  584. SW_FUNC void SWSetFrameRect(
  585.     FramePtr srcFrameP,
  586.     Rect* newFrameRect)
  587. {
  588.     srcFrameP->frameRect = *newFrameRect;
  589.     srcFrameP->frameRowLongs = (newFrameRect->right - newFrameRect->left) >> 2;
  590. }
  591.  
  592.  
  593.